import Foundation
import UIKit
import AsyncDisplayKit
import Display
import TelegramCore
import SwiftSignalKit
import Photos
import TelegramPresentationData
import TelegramUIPreferences
import TelegramStringFormatting
import AccountContext
import GalleryUI
import AppBundle

private let deleteImage = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Accessory Panels/MessageSelectionTrash"), color: .white)
private let actionImage = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Accessory Panels/MessageSelectionForward"), color: .white)

private let nameFont = Font.medium(15.0)
private let dateFont = Font.regular(14.0)

enum AvatarGalleryItemFooterContent {
    case info
    case own(Bool)
}

final class AvatarGalleryItemFooterContentNode: GalleryFooterContentNode {
    private let context: AccountContext
    private var presentationData: PresentationData
    private var strings: PresentationStrings
    private var dateTimeFormat: PresentationDateTimeFormat
    
    private let deleteButton: UIButton
    private let actionButton: UIButton
    private let nameNode: ASTextNode
    private let dateNode: ASTextNode
    private let mainNode: ASTextNode
    private let setMainButton: HighlightableButtonNode
    
    private var currentNameText: String?
    private var currentDateText: String?
    private var currentTypeText: String?
    
    private var validLayout: (CGSize, LayoutMetrics, CGFloat, CGFloat, CGFloat, CGFloat)?
    
    var delete: (() -> Void)? {
        didSet {
            self.deleteButton.isHidden = self.delete == nil
        }
    }
    
    var share: ((GalleryControllerInteraction) -> Void)?
    
    var setMain: (() -> Void)?
    
    init(context: AccountContext, presentationData: PresentationData) {
        self.context = context
        self.presentationData = presentationData
        self.strings = presentationData.strings
        self.dateTimeFormat = presentationData.dateTimeFormat
        
        self.deleteButton = UIButton()
        self.deleteButton.isHidden = true
        
        self.actionButton = UIButton()
        
        self.deleteButton.setImage(deleteImage, for: [.normal])
        self.actionButton.setImage(actionImage, for: [.normal])
        
        self.nameNode = ASTextNode()
        self.nameNode.maximumNumberOfLines = 1
        self.nameNode.isUserInteractionEnabled = false
        self.nameNode.displaysAsynchronously = false
        
        self.dateNode = ASTextNode()
        self.dateNode.maximumNumberOfLines = 1
        self.dateNode.isUserInteractionEnabled = false
        self.dateNode.displaysAsynchronously = false
        
        self.setMainButton = HighlightableButtonNode()
        self.setMainButton.isHidden = true
        
        self.mainNode = ASTextNode()
        self.mainNode.maximumNumberOfLines = 1
        self.mainNode.isUserInteractionEnabled = false
        self.mainNode.displaysAsynchronously = false
        
        super.init()
        
        self.view.addSubview(self.deleteButton)
        self.view.addSubview(self.actionButton)
        
        self.addSubnode(self.nameNode)
        self.addSubnode(self.dateNode)
        self.addSubnode(self.setMainButton)
        self.addSubnode(self.mainNode)
        
        self.deleteButton.addTarget(self, action: #selector(self.deleteButtonPressed), for: [.touchUpInside])
        self.actionButton.addTarget(self, action: #selector(self.actionButtonPressed), for: [.touchUpInside])
        self.setMainButton.addTarget(self, action: #selector(self.setMainButtonPressed), forControlEvents: .touchUpInside)
    }
        
    func setEntry(_ entry: AvatarGalleryEntry, content: AvatarGalleryItemFooterContent) {
        var nameText: String?
        var dateText: String?
        var typeText: String?
        var buttonText: String?
        var canShare = true
        switch entry {
            case let .image(_, _, _, videoRepresentations, peer, date, _, _, _, _, isFallback, _):
                if date != 0 || isFallback {
                    nameText = peer?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? ""
                }
                if let date = date, date != 0 {
                    dateText = humanReadableStringForTimestamp(strings: self.strings, dateTimeFormat: self.dateTimeFormat, timestamp: date).string
                } else if isFallback {
                    dateText = !videoRepresentations.isEmpty ? self.strings.ProfilePhoto_PublicVideo : self.strings.ProfilePhoto_PublicPhoto
                }
                
                if (!videoRepresentations.isEmpty) {
                    typeText = self.strings.ProfilePhoto_MainVideo
                    buttonText = self.strings.ProfilePhoto_SetMainVideo
                } else {
                    typeText = self.strings.ProfilePhoto_MainPhoto
                    buttonText = self.strings.ProfilePhoto_SetMainPhoto
                }
            
                if let peer = peer {
                    canShare = !peer._asPeer().isCopyProtectionEnabled
                }
            default:
                break
        }
        
        if self.currentNameText != nameText || self.currentDateText != dateText {
            self.currentNameText = nameText
            self.currentDateText = dateText
            
            if let nameText = nameText {
                self.nameNode.attributedText = NSAttributedString(string: nameText, font: nameFont, textColor: .white)
            } else {
                self.nameNode.attributedText = nil
            }
            
            if let dateText = dateText {
                self.dateNode.attributedText = NSAttributedString(string: dateText, font: dateFont, textColor: .white)
            } else {
                self.dateNode.attributedText = nil
            }
        }
        
        if self.currentTypeText != typeText {
            self.currentTypeText = typeText
            
            self.mainNode.attributedText = NSAttributedString(string: typeText ?? "", font: Font.regular(17.0), textColor: UIColor(rgb: 0x808080))
            self.setMainButton.setAttributedTitle(NSAttributedString(string: buttonText ?? "", font: Font.regular(17.0), textColor: .white), for: .normal)
            
            if let validLayout = self.validLayout {
                let _ = self.updateLayout(size: validLayout.0, metrics: validLayout.1, leftInset: validLayout.2, rightInset: validLayout.3, bottomInset: validLayout.4, contentInset: validLayout.5, transition: .immediate)
            }
        }
        
        self.actionButton.isHidden = !canShare
        
        switch content {
            case .info:
                self.nameNode.isHidden = false
                self.dateNode.isHidden = false
                self.mainNode.isHidden = true
                self.setMainButton.isHidden = true
            case let .own(isMainPhoto):
                self.nameNode.isHidden = true
                self.dateNode.isHidden = true
                self.mainNode.isHidden = !isMainPhoto
                self.setMainButton.isHidden = isMainPhoto
        }
    }
    
    override func updateLayout(size: CGSize, metrics: LayoutMetrics, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, contentInset: CGFloat, transition: ContainedViewLayoutTransition) -> CGFloat {
        self.validLayout = (size, metrics, leftInset, rightInset, bottomInset, contentInset)
        
        let width = size.width
        var panelHeight: CGFloat = 44.0 + bottomInset
        panelHeight += contentInset
        
        self.actionButton.frame = CGRect(origin: CGPoint(x: leftInset, y: panelHeight - bottomInset - 44.0), size: CGSize(width: 44.0, height: 44.0))
        self.deleteButton.frame = CGRect(origin: CGPoint(x: width - 44.0 - rightInset, y: panelHeight - bottomInset - 44.0), size: CGSize(width: 44.0, height: 44.0))
        
        let constrainedSize = CGSize(width: width - 44.0 * 2.0 - 8.0 * 2.0 - leftInset - rightInset, height: CGFloat.greatestFiniteMagnitude)
        let nameSize = self.nameNode.measure(constrainedSize)
        let dateSize = self.dateNode.measure(constrainedSize)
        
        if nameSize.height.isZero {
            self.dateNode.frame = CGRect(origin: CGPoint(x: floor((width - dateSize.width) / 2.0), y: panelHeight - bottomInset - 44.0 + floor((44.0 - dateSize.height) / 2.0)), size: dateSize)
        } else {
            let labelsSpacing: CGFloat = 0.0
            self.nameNode.frame = CGRect(origin: CGPoint(x: floor((width - nameSize.width) / 2.0), y: panelHeight - bottomInset - 44.0 + floor((44.0 - dateSize.height - nameSize.height - labelsSpacing) / 2.0)), size: nameSize)
            self.dateNode.frame = CGRect(origin: CGPoint(x: floor((width - dateSize.width) / 2.0), y: panelHeight - bottomInset - 44.0 + floor((44.0 - dateSize.height - nameSize.height - labelsSpacing) / 2.0) + nameSize.height + labelsSpacing), size: dateSize)
        }
        
        let mainSize = self.mainNode.measure(constrainedSize)
        self.mainNode.frame = CGRect(origin: CGPoint(x: floor((width - mainSize.width) / 2.0), y: panelHeight - bottomInset - 44.0 + floor((44.0 - mainSize.height) / 2.0)), size: mainSize)
        
        let mainButtonSize = self.setMainButton.measure(constrainedSize)
        self.setMainButton.frame = CGRect(origin: CGPoint(x: floor((width - mainButtonSize.width) / 2.0), y: panelHeight - bottomInset - 44.0 + floor((44.0 - mainButtonSize.height) / 2.0)), size: mainButtonSize)
        
        return panelHeight
    }
    
    override func animateIn(fromHeight: CGFloat, previousContentNode: GalleryFooterContentNode, transition: ContainedViewLayoutTransition) {
        self.deleteButton.alpha = 1.0
        self.actionButton.alpha = 1.0
        self.nameNode.alpha = 1.0
        self.dateNode.alpha = 1.0
        self.setMainButton.alpha = 1.0
    }
    
    override func animateOut(toHeight: CGFloat, nextContentNode: GalleryFooterContentNode, transition: ContainedViewLayoutTransition, completion: @escaping () -> Void) {
        self.deleteButton.alpha = 0.0
        self.actionButton.alpha = 0.0
        self.nameNode.alpha = 0.0
        self.dateNode.alpha = 0.0
        self.setMainButton.alpha = 0.0
        completion()
    }
    
    @objc private func deleteButtonPressed() {
        self.delete?()
    }
    
    @objc private func actionButtonPressed() {
        if let controllerInteraction = self.controllerInteraction {
            self.share?(controllerInteraction)
        }
    }
    
    @objc private func setMainButtonPressed() {
        self.setMain?()
    }
}
